<template>
  <div>
    <div class="container">
      <div class="handle-box">
        <el-button
          type="primary"
          @click="handleAdd"
          v-if="smPermissions.includes('sys:menu:save')"
          >新增</el-button
        >
      </div>
      <el-table :data="tableData" style="width: 100%" border>
        <el-table-column label="名称" align="left" width="180">
          <template slot-scope="scope">
            <div @click="handleRow(scope.$index, scope.row)">
              <span class="space" v-for="i in scope.row.level" :key="i"></span>
              <i
                :class="{
                  'el-icon-caret-right': !scope.row.show,
                  'el-icon-caret-bottom': scope.row.show
                }"
                v-if="scope.row.children && scope.row.children.length"
              ></i>
              <span class="arrow-width" v-else></span>
              <span>{{ scope.row.name }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column align="center" label="图标">
          <template slot-scope="scope">
            <i :class="scope.row.icon"></i>
          </template>
        </el-table-column>

        <el-table-column label="类型" align="center">
          <template slot-scope="scope">
            <el-tag
              :type="
                scope.row.type === '菜单'
                  ? 'success'
                  : scope.row.type === '按钮'
                  ? 'danger'
                  : ''
              "
              >{{ scope.row.type }}</el-tag
            >
          </template>
        </el-table-column>
        <el-table-column prop="sort" align="center" label="排序">
        </el-table-column>
        <el-table-column prop="url" align="center" label="路由">
        </el-table-column>
        <el-table-column
          prop="permissions"
          align="center"
          :show-overflow-tooltip="true"
          label="授权标识"
        >
        </el-table-column>

        <el-table-column label="操作" width="180" align="center">
          <template slot-scope="scope">
            <el-button
              type="text"
              @click="handleEdit(scope.$index, scope.row)"
              v-if="smPermissions.includes('sys:menu:update')"
              >编辑</el-button
            >
            <el-button
              type="text"
              @click="handleDelete(scope.$index, scope.row)"
              v-if="smPermissions.includes('sys:menu:delete')"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 新增弹出框 0=>菜单 1=>按钮 -->
    <el-dialog title="新增" :visible.sync="addVisible" width="50%">
      <el-form ref="addForm" :model="addForm" label-width="auto" :rules="rules">
        <el-form-item label="类型">
          <template>
            <el-radio-group v-model="addForm.type" @change="singleChange">
              <el-radio :label="0">菜单</el-radio>
              <el-radio :label="1">按钮</el-radio>
            </el-radio-group>
          </template>
        </el-form-item>

        <el-form-item label="名称" prop="name" v-if="addForm.type === 0">
          <el-input
            v-model="addForm.name"
            placeholder="名称"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item label="名称" prop="name" v-if="addForm.type === 1">
          <el-input
            v-model="addForm.name"
            placeholder="名称"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item
          label="上级菜单"
          prop="parentName"
          v-if="addForm.type === 0"
        >
          <div class="block">
            <el-cascader
              :options="addForm.options"
              :placeholder="'请选择上级菜单'"
              clearable
              :props="{ checkStrictly: true }"
              @change="valueChange"
              :disabled="addForm.options.length == 0"
              ref="cascader"
              v-model="deptvalue"
            ></el-cascader>
          </div>
        </el-form-item>

        <el-form-item
          label="上级菜单"
          prop="parentName"
          v-if="addForm.type === 1"
        >
          <div class="block">
            <el-cascader
              :options="addForm.options"
              :props="{ checkStrictly: true }"
              clearable
              @change="valueChange"
              :disabled="optionsChanged"
              ref="cascader"
              v-model="deptvalue"
            ></el-cascader>
          </div>
        </el-form-item>

        <el-form-item label="路由" prop="url" v-if="addForm.type === 0">
          <el-input
            placeholder="路由"
            v-model="addForm.url"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item label="排序" v-if="addForm.type === 0">
          <template>
            <el-input-number
              v-model="addForm.sort"
              @change="handleChange"
              :min="0"
              :max="Infinity"
              label="描述文字"
            ></el-input-number>
          </template>
        </el-form-item>

        <el-form-item label="排序" v-if="addForm.type === 1">
          <template>
            <el-input-number
              v-model="addForm.sort"
              @change="handleChange"
              :min="0"
              :max="Infinity"
              label="描述文字"
            ></el-input-number>
          </template>
        </el-form-item>

        <el-form-item
          label="授权标识"
          prop="permissions"
          v-if="addForm.type === 0"
        >
          <el-input
            v-model="addForm.permissions"
            placeholder="多个用逗号隔开, 如: sys:menu:save,sys:menu:update"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item
          label="授权标识"
          prop="permissions"
          v-if="addForm.type === 1"
        >
          <el-input
            v-model="addForm.permissions"
            placeholder="多个用逗号隔开, 如: sys:menu:save,sys:menu:update"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item label="图标" prop="icon" v-if="addForm.type === 0">
          <template>
            <el-select
              style="width: 195px;"
              v-model="addForm.value"
              placeholder="图标"
            >
              <el-option
                v-for="(item, index) in addForm.icons"
                :key="index"
                :label="addForm.icon"
                :value="addForm.icon"
              >
                <span
                  v-for="(icon, index) in item"
                  :key="index"
                  @click="selectIcon(icon)"
                  :style="{ margin: '0 2px 2px 2px' }"
                >
                  <el-button
                    type="default"
                    size="mini"
                    circle
                    :icon="icon"
                  ></el-button>
                </span>
              </el-option>
            </el-select>
          </template>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addVisible = false">取消</el-button>
        <el-button type="primary" @click="saveAdd">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 编辑弹出框 0 => 菜单  1 => 按钮-->
    <el-dialog title="编辑" :visible.sync="editVisible" width="50%">
      <el-form ref="editForm" :model="editForm" label-width="auto">
        <el-form-item label="类型">
          <template>
            <el-radio-group v-model="editForm.type" @change="singleChange">
              <el-radio disabled :label="0">菜单</el-radio>
              <el-radio disabled :label="1">按钮</el-radio>
            </el-radio-group>
          </template>
        </el-form-item>
        <el-form-item label="名称" prop="name" v-if="editForm.type === 0">
          <el-input
            v-model="editForm.name"
            placeholder="名称"
            clearable
          ></el-input>
        </el-form-item>
        <el-form-item
          label="上级菜单"
          prop="parentName"
          v-if="editForm.type == 0"
        >
          <div class="block">
            <el-cascader
              :options="editForm.options"
              :props="{ checkStrictly: true }"
              clearable
              @change="valueChange"
              :disabled="optionsChanged"
              :key="isResouceShow"
              ref="cascader"
              v-model="deptvalue"
            ></el-cascader>
          </div>
        </el-form-item>

        <el-form-item
          label="上级菜单"
          prop="parentName"
          v-if="editForm.type === 1"
        >
          <div class="block">
            <el-cascader
              :options="editForm.options"
              :props="{ checkStrictly: true }"
              clearable
              @change="valueChange"
              :disabled="optionsChanged"
              :key="isResouceShow"
              ref="cascader"
              v-model="deptvalue"
            ></el-cascader>
          </div>
        </el-form-item>
        <el-form-item label="路由" prop="url" v-if="editForm.type === 0">
          <el-input
            v-model="editForm.url"
            placeholder="路由"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item label="排序" v-if="editForm.type === 0">
          <template>
            <el-input-number
              v-model="editForm.sort"
              @change="handleChange"
              :min="0"
              :max="Infinity"
              label="描述文字"
            ></el-input-number>
          </template>
        </el-form-item>

        <el-form-item label="排序" v-if="editForm.type === 1">
          <template>
            <el-input-number
              v-model="editForm.sort"
              @change="handleChange"
              :min="0"
              :max="Infinity"
              label="描述文字"
            ></el-input-number>
          </template>
        </el-form-item>

        <el-form-item label="图标" prop="icon" v-if="addForm.type === 0">
          <template>
            <el-select
              style="width: 195px;"
              v-model="editForm.icon"
              placeholder="图标"
            >
              <el-option
                v-for="(item, index) in icons"
                :key="index"
                :label="editForm.icon"
                :value="editForm.icon"
              >
                <span
                  v-for="(icon, index) in item"
                  :key="index"
                  @click="selectIcon(icon)"
                  :style="{ margin: '0 2px 2px 2px' }"
                >
                  <el-button
                    type="default"
                    size="mini"
                    circle
                    :icon="icon"
                  ></el-button>
                </span>
              </el-option>
            </el-select>
          </template>
        </el-form-item>

        <el-form-item
          label="授权标识"
          prop="permissions"
          v-if="editForm.type === 0"
        >
          <el-input
            v-model="editForm.permissions"
            placeholder="多个用逗号隔开, 如: sys:menu:save,sys:menu:update"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item
          label="授权标识"
          prop="permissions"
          v-if="editForm.type === 1"
        >
          <el-input
            v-model="editForm.permissions"
            placeholder="多个用逗号隔开, 如: sys:menu:save,sys:menu:update"
            clearable
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveEdit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import icons from "@/components/common/icons.js";
// import { sysMenuMixin } from "common/js/systemSettings";
import util from "utils/util";
import { mapGetters } from "vuex";
export default {
  name: "sysmenu",
  // mixins: [sysMenuMixin],
  data() {
    return {
      smPermissions: [],
      icons: icons,
      options: [
        {
          value: "",
          label: ""
        }
      ],
      editVisible: false,
      addVisible: false,
      rules: {
        name: [{ required: true, message: "必填不能为空", trigger: "blur" }],
        parentName: [
          { required: false, message: "必填不能为空", trigger: "blur" }
        ]
      },
      editForm: {
        id: "",
        pid: "0",
        children: [],
        name: "",
        url: null,
        type: 0,
        icon: "",
        permissions: null,
        sort: 0,
        createDate: null,
        parentName: null,
        options: []
      },
      addForm: {
        id: "",
        pid: "0",
        children: [],
        name: "",
        url: null,
        type: 0,
        icon: "",
        permissions: null,
        sort: 0,
        createDate: null,
        parentName: null,
        options: [],
        value: "",
        icons: icons
      },
      form: {
        name: ""
      },
      tableData: [
        {
          id: "",
          pid: "",
          children: [],
          name: "",
          url: null,
          type: 0,
          icon: "",
          permissions: null,
          sort: 0,
          createDate: null,
          parentName: null
        }
      ],
      optionsChanged: false,
      isResouceShow: 0,
      deptvalue: []
    };
  },
  created() {
    // 获取数据
    this.getSMData({});
    this.smPermissions = this.permissions;
  },
  computed: {
    ...mapGetters(["permissions"])
  },
  watch: {
    deptvalue() {
      if (this.$refs.cascader) {
        this.$refs.cascader.dropDownVisible = false;
      }
    },
    "$route.path": function(newVal, oldVal) {
      if (newVal == "/sys-menu") {
        this.smPermissions = this.permissions;
      }
    },
    // 刷新浏览器时触发
    permissions: function(newVal, oldVal) {
      // console.log(newVal, oldVal);
      this.smPermissions = newVal;
    }
  },
  methods: {
    selectIcon(icon) {
      console.log(icon);
      this.options[0].label = icon;
      this.options[0].value = icon;
      this.addForm.icon = icon;
      this.editForm.icon = icon;
    },
    // 获取数据
    getSMData({ order = "", orderField = "", _t = Date.now() }) {
      this.$axios
        .get("/sys/menu/list", {
          params: {
            order,
            orderField,
            _t
          }
        })
        .then(({ data: res }) => {
          console.log("菜单管理", res);
          if (res.code !== 0) {
            return;
          }
          function myMap(array) {
            array.map(item => {
              item.show = false;
              if (item.children && item.children.length) {
                return myMap(item.children);
              }
            });
          }
          myMap(res.data);

          function handleType(array) {
            array.map(item => {
              item.type = item.type === 0 ? "菜单" : "按钮";
              if (item.children && item.children.length) {
                return handleType(item.children);
              }
            });
          }
          handleType(res.data);
          this.tableData = res.data;
          this.tableData.map(item => {
            item.show = false;
            item.level = 0;
            if (item.children && item.children.length) {
              item.children.map(subItem => {
                subItem.show = false;
                subItem.level = 1;
                if (subItem.children && subItem.children.length) {
                  subItem.children.map(grandsonItem => {
                    grandsonItem.show = false;
                    grandsonItem.level = 2;
                  });
                }
              });
            }
          });
        })
        .catch(() => {});
    },
    // 排序
    handleChange(currentValue, oldValue) {
      if (this.addVisible) {
        this.addForm.sort = currentValue;
      } else if (this.editVisible) {
        this.editForm.sort = currentValue;
      }
    },
    saveAdd() {
      // 得到成功提示
      this.$axios
        .post("/sys/menu", {
          type: this.addForm.type,
          name: this.addForm.name,
          pid: this.addForm.pid,
          parentName: this.addForm.parentName,
          url: this.addForm.url,
          permissions: this.addForm.permissions,
          sort: this.addForm.sort,
          icon: this.addForm.icon
        })
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return;
          }
          this.$message.success("操作成功");
          this.addVisible = false;
          this.addForm = {
            id: "",
            pid: "0",
            children: [],
            name: "",
            url: null,
            type: 0,
            icon: "",
            permissions: null,
            sort: 0,
            createDate: null,
            parentName: null,
            options: [],
            value: "",
            icons: icons
          };
          this.getSMData({});
        })
        .catch(() => {});
    },
    // 菜单或按钮
    singleChange(value) {
      // 0为菜单 1为按钮
      if (this.addVisible) {
        this.addForm.type = value;
      } else if (this.editVisible) {
        this.editForm.type = value;
      }
    },
    // 初始化上级菜单
    initParaentMenu() {
      this.$axios
        .get("/sys/menu/list", {
          params: {
            type: this.addForm.type,
            _t: Date.now()
          }
        })
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return;
          }

          if (this.addVisible) {
            this.addLabelAttribute(res.data);
            console.log(res.data);
            // var tempObj = {};
            for (var i = 0; i < res.data.length; i++) {
              var {
                createDate,
                icon,
                id,
                label,
                name,
                parentName,
                permissions,
                pid,
                sort,
                type,
                url,
                value
              } = res.data[i];
              var tempObj = {
                createDate,
                icon,
                id,
                label,
                name,
                parentName,
                permissions,
                pid,
                sort,
                type,
                url,
                value,
                children: []
              };

              if (res.data[i].children && res.data[i].children.length) {
                for (var j = 0; j < res.data[i].children.length; j++) {
                  var {
                    createDate,
                    icon,
                    id,
                    label,
                    name,
                    parentName,
                    permissions,
                    pid,
                    sort,
                    type,
                    url,
                    value
                  } = res.data[i].children[j];
                  tempObj.children.push({
                    createDate,
                    icon,
                    id,
                    label,
                    name,
                    parentName,
                    permissions,
                    pid,
                    sort,
                    type,
                    url,
                    value
                  });
                }
              }

              this.addForm.options.push(tempObj);
              console.log(this.addForm.options);
              console.log(res.data[i]);
            }
            console.log(this.addForm.options);
          } else if (this.editVisible) {
            this.addLabelAttribute(res.data);
            this.editForm.options = res.data;
          }
        })
        .catch(() => {});
    },
    // 递归思想: 添加label属性
    addLabelAttribute(arr) {
      for (var i = 0; i < arr.length; i++) {
        if ("children" in arr[i] && arr[i].children.length !== 0) {
          arr[i].label = arr[i].name;
          arr[i].value = arr[i].name;
          this.addLabelAttribute(arr[i].children);
        } else if ("children" in arr[i] && arr[i].children.length === 0) {
          arr[i].label = arr[i].name;
          arr[i].value = arr[i].name;
          delete arr[i].children;
        } else if (!("children" in arr[i])) {
          arr[i].label = arr[i].name;
          arr[i].value = arr[i].name;
        }
      }
    },
    // 新增
    handleAdd() {
      this.addVisible = true;
      this.addForm.options = [];
      // 初始化上级菜单
      this.initParaentMenu();
    },

    // 保存编辑
    saveEdit() {
      // 得到成功提示
      this.$axios
        .put("/sys/menu", {
          id: this.editForm.id,
          pid: this.editForm.pid,
          name: this.editForm.name,
          url: this.editForm.url,
          type: this.editForm.type,
          icon: this.editForm.icon,
          permissions: this.editForm.permissions,
          sort: this.editForm.sort
        })
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return;
          }
          this.$message.success("操作成功");
          this.editVisible = false;
          this.getSMData({});
        })
        .catch(() => {});
    },
    // 编辑操作
    handleEdit(index, row) {
      this.idx = index;
      this.editVisible = true;

      if (row.type === "按钮") {
        this.editForm.type = 1;
      } else {
        this.editForm.type = 0;
      }

      // 初始化上级菜单 editForm.options: []
      this.initParaentMenu();
      // 初始化编辑表单页面
      this.$axios
        .get("/sys/menu/" + row.id, {
          _t: Date.now(),
          type: this.editForm.type
        })
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return;
          }
          console.log("编辑数据", res);
          for (var key in res.data) {
            this.editForm[key] = res.data[key];
          }
          console.log(this.editForm);
        })
        .catch(() => {});
    },
    // 上级菜单 根据name找到父级id 设置给子级的pid
    valueChange(value) {
      console.log(value);
      if (this.addVisible) {
        value = value[value.length - 1];
        this.addForm.parentName = value;
        console.log("上级菜单", this.addForm.options);
        var str = "";
        var options = Array.from(this.addForm.options);

        var bool = false;
        for (var item of options) {
          if (item.name == value) {
            str = item.id;
            break;
          } else {
            var children = Array.from(item.children);

            for (var child of children) {
              if (child.name == value) {
                str = child.id;
                bool = true;
                break;
              }
            }
          }
          if (bool) {
            break;
          }
        }
        console.log(str);
        this.addForm.pid = str;
      } else if (this.editVisible) {
        value = value[value.length - 1];
        this.editForm.parentName = value;
        // 根据name找到父级id 设置给子级的pid
        function myMap(array, name) {
          var arr = array.map(item => {
            if (item.name === name) {
              return item.id;
            } else {
              if (item.children && item.children.length) {
                return myMap(item.children, name);
              }
            }
          });
          return arr;
        }
        var result = myMap(this.editForm.options, value);
        var str = "";
        function recursion(array) {
          for (var item of array) {
            if (item === undefined) {
              continue;
            } else if (
              item !== undefined &&
              Object.prototype.toString.call(item) === "[object Array]"
            ) {
              recursion(item);
            } else {
              str = item;
            }
          }
        }
        recursion(result);
        this.editForm.pid = str;
      }
    },
    // 删除操作
    handleDelete(index, row) {
      util.singleDelete.call(this, "/sys/menu/", index, row.id, this.getSMData);
    },
    handleRow(index, row) {
      index++;
      if (row.children && row.children.length > 0) {
        if (row.show) {
          row.show = false;
          var length = row.children.length;
          function myMap(array) {
            array.map(item => {
              if (item.show) {
                item.show = false;
                length += item.children.length;
                return myMap(item.children);
              }
            });
          }
          myMap(row.children);
          this.tableData.splice(index, length);
        } else {
          row.children.forEach(value => {
            this.tableData.splice(index, 0, value);
            index++;
          });
          row.show = true;
        }
      }
    }
  }
};
</script>
<style lang="scss">
@import "../../common/css/base.css";
</style>
